package com.coda.service.impl;

import com.coda.context.BaseContext;
import com.coda.mapper.StatisticsMapper;
import com.coda.mapper.WordMapper;
import com.coda.pojo.Statistics;
import com.coda.pojo.Word;
import com.coda.pojo.dto.WordDTO;
import com.coda.pojo.vo.BeforeSevenDaysDictationVo;
import com.coda.pojo.vo.UserRankVo;
import com.coda.pojo.vo.WordGardAndStatusVo;
import com.coda.service.StatisticsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

/**
 * 统计serviceImpl
 */
@Service
public class StatisticsServiceImpl implements StatisticsService {

    @Autowired
    private StatisticsMapper statisticsMapper;
    @Autowired
    private WordMapper wordMapper;

    @Override
    public Statistics getWordStatistics(Integer currentId) {
        //获取已经默写总数和每日目标
        Statistics result =  statisticsMapper.getWordStatistics(currentId);
        //获取连续天数
        int getLongestDays =  statisticsMapper.getLongestDays(currentId);
        //获取单词总数
        List<Word> list = wordMapper.getWordAll(new WordDTO());
        int total = list.size();
        //获取次数
        int dictationCount = statisticsMapper.getDictationTotal(currentId);
        //获取总默写次数
        int correctTotal = statisticsMapper.getCorrectTotal(currentId);
        //正确的概率
        String dictationAccuracy = "";
        if (correctTotal == 0 ) {
            dictationAccuracy = "0.0%";
        }else {
            double percentage = (double) correctTotal / dictationCount * 100;
            dictationAccuracy = String.format("%.1f%%", percentage);
        }
        result.setTotal(total);
        result.setLongestDays(getLongestDays);
        result.setDictationAccuracy(dictationAccuracy);
        return result;
    }

    /**
     * 最近一周的默写统计
     * @return
     */
    @Override
    public List<BeforeSevenDaysDictationVo> getBeforeWeek() {
        //村数据的集合
        List<BeforeSevenDaysDictationVo> days = new ArrayList<>();
        //最近一周日期
        ArrayList<LocalDate> week = getWeek();

        //遍历日期获取对应数据
        for (int i = 0; i < week.size(); i++) {
            //日期
            LocalDate date = week.get(i);
            //获取对应日期默写的单词个数
            int count = statisticsMapper.getWeekWordCount(BaseContext.getCurrentId(),date);
            //获取对应的周号
            String weekDay = getChineseWeekDay(date);

            //创建对象设置数据
            BeforeSevenDaysDictationVo beforeSeven = new BeforeSevenDaysDictationVo();
            beforeSeven.setDate(date);
            beforeSeven.setTotal(count);
            beforeSeven.setDayOfWeek(weekDay);

            //存储数据
            days.add(beforeSeven);
        }
        return days;
    }

    /**
     * 查询所有单词难度等级，以及状态个数
     * @return
     */
    @Override
    public WordGardAndStatusVo getGardAndStatusCount() {
        List<Word> wordAll = wordMapper.getWordAll(new WordDTO());
        //统计个数
        int easy = 0;
        int medium = 0;
        int difficulty = 0;
        for (int i = 0; i < wordAll.size(); i++) {
            Word word = wordAll.get(i);
            String hard = word.getDifficulty();
            if ("1".equals(hard)){
                easy++;
            }else if ("2".equals(hard)){
                medium++;
            }else{
                difficulty++;
            }
        }
        //设置属性
        WordGardAndStatusVo wordGardAndStatusVo = new WordGardAndStatusVo();
        wordGardAndStatusVo.setEasy(easy);
        wordGardAndStatusVo.setMedium(medium);
        wordGardAndStatusVo.setDifficulty(difficulty);
        return wordGardAndStatusVo;
    }

    /**
     * 获取前单词默写数量前六名的用户
     * @return
     */
    @Override
    public List<UserRankVo> getUserRank() {
        return statisticsMapper.getUserRank();
    }

    /**
     * 获取当前用户错误次数最多的20个单词
     * @return
     */
    @Override
    public List<Word> getIncorrectCount() {
        return statisticsMapper.getIncorrectCount();
    }

    /**
     * 计算星期几
     * @param date
     * @return
     */
    public String getChineseWeekDay(LocalDate date) {
        DayOfWeek dayOfWeek = date.getDayOfWeek();
        switch (dayOfWeek) {
            case MONDAY: return "周一";
            case TUESDAY: return "周二";
            case WEDNESDAY: return "周三";
            case THURSDAY: return "周四";
            case FRIDAY: return "周五";
            case SATURDAY: return "周六";
            case SUNDAY: return "周日";
            default: return "";
        }
    }

    /**
     * 获取最近一周
     */
    public ArrayList<LocalDate> getWeek() {
        ArrayList<LocalDate> days = new ArrayList<>();
        LocalDate  nowDay = LocalDate.now();
        for (int i = 6; i >=0 ; i--) {
            LocalDate day = nowDay.minusDays(i);
            days.add(day);
        }
        return days;
    }
}
